package entity

import (
	comment "center-platform/internal/controller/v1/comment/entity"
	user "center-platform/internal/controller/v1/user/entity"
	"center-platform/utils"
	"gorm.io/gorm"
	"sync"
	"time"
)

type Post struct {
	ID         int       `json:"id" gorm:"primary_key;column:id"`
	Title      string    `json:"title" gorm:"column:title" binding:"required"`
	UserID     int       `json:"user_id" gorm:"column:user_id;index"`
	Tags       string    `json:"tags" gorm:"column:tags"`
	Post       string    `json:"post" gorm:"column:post" binding:"required"`
	Status     int8      `json:"status" gorm:"column:status"` // 0-待审核 1-正常 2-锁定 -1-已删除
	LikeCount  int       `json:"like_count" gorm:"column:like_count"`
	ShareCount int       `json:"share_count" gorm:"column:share_count"`
	CreatedAt  time.Time `json:"created_at" gorm:"column:created_at"`
	UpdatedAt  time.Time `json:"updated_at" gorm:"column:updated_at"`

	User    user.UserBasicInfoResponse `json:"user" gorm:"foreignKey:UserID"`
	Comment []comment.Comment          `json:"comment" gorm:"foreignKey:PostID"`
}

type SearchParam struct {
	Ids      []int    `json:"ids"`
	Title    string   `json:"title"`
	UserIds  []int    `json:"user_ids"`
	Tags     []string `json:"tags"`
	Status   []int8   `json:"status"`
	Page     int      `json:"page" binding:"required" validate:"min:1"`
	PageSize int      `json:"page_size" binding:"required" validate:"min:1"`
}

var lock sync.Mutex

func (d *Post) Create() error {
	err := utils.DB.Omit("User").Create(d).Error
	if err != nil {
		return err
	}
	return nil
}

func (d *Post) GetInfoById(id int) (error, *Post) {
	err := utils.DB.Model(d).Preload("User").Preload("Comment", "status = 1").Where("posts.id = ?", id).First(d).Error
	if err != nil {
		return err, nil
	}
	return nil, d
}

func (d *Post) List(where interface{}, offset int, limit int, args ...interface{}) (error, []Post) {
	var results []Post
	err := utils.DB.Model(d).Preload("User").Preload("Comment", "status = 1").Preload("Comment.User").Where(where, args...).Offset(offset).Limit(limit).Find(&results).Error
	if err != nil {
		return err, nil
	}
	return nil, results
}

func (d *Post) Update(where interface{}, update map[string]interface{}, args ...interface{}) error {
	lock.Lock()
	err := utils.DB.Model(d).Where(where, args...).Updates(update).Error
	if err != nil {
		return err
	}
	lock.Unlock()
	return nil
}

func (d *Post) Delete(where string, args ...interface{}) error {
	if len(where) == 0 {
		return gorm.ErrMissingWhereClause
	}
	if err := utils.DB.Where(where, args...).Delete(d).Error; err != nil {
		return err
	}
	return nil
}
